import java.util.ArrayList;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.el.FixedValue;

import org.activiti.engine.impl.el.Expression;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.json.JSONObject;
import org.restlet.Client;
import org.restlet.Context;
import org.restlet.Response;

import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.ext.json.*;
import org.restlet.resource.ClientResource;
import org.restlet.Request;

public class RestDelegate implements JavaDelegate
{

	private FixedValue method;
	private Expression url;
	private FixedValue returnValue;
	private Expression parameter;
	private FixedValue basicUser;
	private FixedValue basicPasswd;

	@SuppressWarnings("unused")
	public void execute (DelegateExecution execution) throws Exception
	{
		// Get project properties
		String projectID = (String)parameter.getValue(execution);
		String desc = getProjectDescription(projectID);
		Double price = getProjectPrice(projectID);

		if(price == null) price = 0.0;

		Project pr = new Project(projectID, desc);
		pr.setPrice(price);

		if(pr == null)
		{
			throw new IllegalArgumentException("Could not load project: " + (String)parameter.getValue(execution));
		}
		System.out.println("Project to send to the rest service: "+ pr.toJSON().toString());
		String methodName = (String)method.getValue(execution);
		System.out.println("Method name: "+ methodName );

		Client restletClient = new Client (new Context(), Protocol.HTTP);
		String urlString = (String) url.getValue(execution);

		if ((methodName.equals("GET"))) {
			Request request = new Request (Method.GET, new Reference (urlString));

			if (basicUser!=null && basicPasswd!=null) {
				ChallengeResponse authentication = new ChallengeResponse(ChallengeScheme.HTTP_BASIC, (String)basicUser.getExpressionText(), (String)basicPasswd.getExpressionText());
				request.setChallengeResponse(authentication);
			}

			Response response = restletClient.handle(request);
			String responseAsText = response.getEntityAsText();
			// String responseAsText = response.

			if(responseAsText!=null) {
				String returnVariableName = (String) returnValue.getValue(execution);
				execution.setVariable(returnVariableName, responseAsText);
				System.out.println("Return value: "+ responseAsText );
			}
		}
		else 
		{
			if (methodName.equals("POST"))
			{
				// TODO remove this when project loading works
				// Project pr = new Project("TEST_address", "TEST_description");

				JSONObject js = pr.toJSON();
				System.out.println("JSON content: " + js.toString());
				//Request request = new Request (Method.POST, new Reference (urlString));
				JsonRepresentation rep = new JsonRepresentation(js);
				System.out.println(rep.toString());
				// rep.setMediaType(MediaType.);

				ClientResource requestResource = new ClientResource(urlString);
				requestResource.post(rep, MediaType.APPLICATION_JSON);

				Status st = requestResource.getResponse().getStatus();

				if(st.isSuccess()){
					System.out.println("Super toll");
				}

				// if(reply!=null) {
				// String returnVariableName = (String) returnValue.getValue(execution);
				// execution.setVariable(returnVariableName, reply.getText());
				// System.out.println("Return value: "+ reply.getText() );
				// }
			}
			else
			{
				throw new IllegalArgumentException("Method '" + methodName + "' not supported from RestDelegate for now");
			}
		}
	}

	private String getProjectDescription (String id){
		String wsdlString = "http://localhost:63081/projectContainer?wsdl";
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		org.apache.cxf.endpoint.Client client = dcf.createClient(wsdlString);

		ArrayList<String> paramStrings = new ArrayList<String>();
		paramStrings.add(id);

		Object[] response = null;
		try {
			response = client.invoke("getProjectDescription", paramStrings.toArray(new Object[0]));
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(response[0]);

		return (String)response[0];
	}

	private Double getProjectPrice (String id){
		String wsdlString = "http://localhost:63081/projectContainer?wsdl";
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		org.apache.cxf.endpoint.Client client = dcf.createClient(wsdlString);

		ArrayList<String> paramStrings = new ArrayList<String>();
		paramStrings.add(id);

		Object[] response = null;
		try {
			response = client.invoke("getProjectPrice", paramStrings.toArray(new Object[0]));
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(response[0]);

		return Double.parseDouble((String) response[0]);
	}
}
